/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.support;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

/**
 * 
 *
 * @author haolw
 * @time 2016/10/10
 */
public class SqlSessionFactorySupport extends SqlSessionFactoryBean {
	private final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

	@Override
	public void setTypeAliasesPackage(String typeAliasesPackage) {
		patternPackage(typeAliasesPackage);
	}

	/**
	 * ant pattern scan
	 * 
	 * @param typeAliasesPackage
	 */
	protected void patternPackage(String packagePath) {
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
		String typeAliasesPackage = buildPackage(packagePath);
		try {
			Set<String> packages = new HashSet<String>(16);
			Resource[] resources = resolver.getResources(typeAliasesPackage);
			if (resources != null && resources.length > 0) {
				MetadataReader metadataReader = null;
				for (Resource resource : resources) {
					if (resource.isReadable()) {
						metadataReader = metadataReaderFactory.getMetadataReader(resource);
						String className = metadataReader.getClassMetadata().getClassName();
						String packageName = ClassUtils.getPackageName(className);
						packages.add(packageName);
					}
				}
			}
			String aliasesPackage = packagePath;
			if (packages.size() > 0) {
				aliasesPackage = StringUtils.join(packages.toArray(), ",");
			}
			super.setTypeAliasesPackage(aliasesPackage);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * wrap package
	 * 
	 * @param typeAliasesPackage
	 * @return
	 */
	protected String buildPackage(String typeAliasesPackage) {
		StringBuilder packageBuilder = new StringBuilder();
		packageBuilder.append(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX);
		packageBuilder.append(ClassUtils.convertClassNameToResourcePath(typeAliasesPackage));
		packageBuilder.append("/");
		packageBuilder.append(DEFAULT_RESOURCE_PATTERN);
		return packageBuilder.toString();
	}

}
